import {Point} from "./Point";
import {Shape} from "@/utils/Shape";

export class Line extends Shape {

  begin: Point;
  points: Point[];

  constructor(ctx: CanvasRenderingContext2D, x: number, y: number) {
    super(ctx, x, y)
    this.begin = new Point(x, y)
    this.points = []

    this.ctx.beginPath()
    this.ctx.moveTo(x, y)
  }

  drawMove(x: number, y: number) {
    const point = new Point(x, y)

    if (!point.samePoint(this.points[0] || this.begin)) {
      this.lineTo(point)
      this.points.push(point)
    }

    return this
  }

  drawEnd(x: number, y: number) {
    if (this.points.length) {
      return this
    }
  }

  async playback() {
    this.ctx.beginPath()
    this.ctx.strokeStyle = this.strokeStyle
    this.ctx.lineWidth = this.lineWidth
    this.moveTo(this.begin)

    for (const point of this.points) {
      await this.asyncLineTo(point)
    }
  }

  moveTo({x, y}: Point) {
    this.ctx.moveTo(x, y)
  }

  lineTo({x, y}: Point) {
    this.ctx.lineTo(x, y)
    this.ctx.stroke()
  }

  asyncLineTo(point: Point) {
    return new Promise(resolve => {
      requestAnimationFrame(() => {
        this.lineTo(point)
        resolve(true)
      })
    })
  }

  draw(activeShapeId: string = '', ctx?: CanvasRenderingContext2D) {
    if (!ctx) {
      ctx = this.ctx
    }

    ctx.beginPath()
    ctx.strokeStyle = this.strokeStyle

    if (activeShapeId === this.id) {
      ctx.lineWidth = this.lineWidth + 4
    } else {
      ctx.lineWidth = this.lineWidth
    }

    ctx.moveTo(this.begin.x, this.begin.y)

    for (const point of this.points) {
      ctx.lineTo(point.x, point.y)
      ctx.stroke()
    }
  }

  drawEventCanvas(ctx: CanvasRenderingContext2D): void {
    this.draw(undefined, this.ctx)
  }
}
